import cv2
from matplotlib import pyplot as plt
import numpy as np
from skimage.util import random_noise

img = cv2.imread('原图.jpg')  # 读取图像

# 获取图像中某一点的BGR像素值
(b, g, r) = img[100, 100]
print(b, g, r)

# 显示原始图像
plt.imshow(img)
plt.show()

rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # 将BGR图像转换为RGB格式
plt.imshow(rgb_img)
plt.show()

gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转换为灰度图
plt.imshow(gray_img, cmap='gray')
plt.show()

sp_noise_img = random_noise(rgb_img, mode='s&p', amount=0.3)  # 添加椒盐噪声
gus_noise_img = random_noise(rgb_img, mode='gaussian')  # 添加高斯噪声

# 显示噪声图像
plt.subplot(1, 3, 1)
plt.imshow(rgb_img, cmap='gray')
plt.subplot(1, 3, 2)
plt.imshow(sp_noise_img, cmap='gray')
plt.subplot(1, 3, 3)
plt.imshow(gus_noise_img, cmap='gray')

mid_3 = cv2.medianBlur((sp_noise_img*255).astype(np.uint8), 3)  # 使用OpenCV自带的中值滤波器
gus_3 = cv2.blur(gus_noise_img, (3, 3))  # 使用OpenCV自带的高斯滤波器

def manual_mean_filter(image, kernel_size=3):
    """
    手动实现均值滤波器
    :param image: 输入图像（归一化到[0,1]的浮点图像）
    :param kernel_size: 滤波核大小
    :return: 滤波后的图像
    """
    pad = kernel_size // 2
    h, w, c = image.shape
    filtered = np.zeros_like(image)

    # 对图像进行边缘填充
    padded = np.pad(image, ((pad, pad), (pad, pad), (0, 0)), mode='edge')

    # 遍历每个像素，计算邻域均值
    for i in range(h):
        for j in range(w):
            for k in range(c):
                region = padded[i:i + kernel_size, j:j + kernel_size, k]
                filtered[i, j, k] = np.mean(region)
    return filtered

# 对手动实现的均值滤波器进行测试
mean_3 = manual_mean_filter(sp_noise_img, kernel_size=3)

# 显示滤波结果
plt.subplot(1, 4, 1)
plt.imshow(sp_noise_img, cmap='gray')
plt.subplot(1, 4, 2)
plt.imshow(mean_3, cmap='gray')
plt.subplot(1, 4, 3)
plt.imshow(mid_3, cmap='gray')
plt.subplot(1, 4, 4)
plt.imshow(gus_3, cmap='gray')

# 模板匹配
template = cv2.imread("tmp.jpg")
# 使用归一化相关系数匹配方法
result = cv2.matchTemplate(rgb_img, template, cv2.TM_CCOEFF_NORMED)
best_idx = np.argmax(result)
best_loc = np.unravel_index(best_idx, result.shape)

h, w = template.shape[:2]
top_left = (best_loc[1], best_loc[0])
bottom_right = (top_left[0] + w, top_left[1] + h)
cv2.rectangle(rgb_img, top_left, bottom_right, 255, 2)
plt.imshow(rgb_img)
